const express = require('express');
const jwt = require('jsonwebtoken');

// 动态引入 node-fetch（v3 为 ESM，CommonJS 需要动态 import）
const fetch = (...args) => import('node-fetch').then(({ default: fetch }) => fetch(...args));

const User = require('../models/User');

const router = express.Router();

// 读取环境变量
const WECHAT_APPID = process.env.WECHAT_APPID;
const WECHAT_APP_SECRET = process.env.WECHAT_APP_SECRET;
const JWT_SECRET = process.env.JWT_SECRET;
const JWT_EXPIRES_IN = process.env.JWT_EXPIRES_IN || '30d';

if (!WECHAT_APPID || !WECHAT_APP_SECRET) {
  // 仅在路由加载时提示一次，便于排查
  console.warn('[wechat] 缺少 WECHAT_APPID/WECHAT_APP_SECRET 环境变量，微信相关接口将不可用');
}

// 简单内存缓存 access_token
const tokenCache = {
  accessToken: null,
  expiresAt: 0,
};

async function getAccessToken() {
  const now = Date.now();
  if (tokenCache.accessToken && tokenCache.expiresAt - now > 120000) {
    return tokenCache.accessToken;
  }
  const url = `https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=${WECHAT_APPID}&secret=${WECHAT_APP_SECRET}`;
  const resp = await fetch(url);
  const data = await resp.json();
  if (data.errcode) {
    throw new Error(`获取access_token失败: [${data.errcode}] ${data.errmsg}`);
  }
  tokenCache.accessToken = data.access_token;
  tokenCache.expiresAt = now + (data.expires_in || 7200) * 1000;
  return tokenCache.accessToken;
}

async function jscode2session(code) {
  const url = `https://api.weixin.qq.com/sns/jscode2session?appid=${WECHAT_APPID}&secret=${WECHAT_APP_SECRET}&js_code=${encodeURIComponent(code)}&grant_type=authorization_code`;
  const resp = await fetch(url);
  const data = await resp.json();
  if (data.errcode) {
    throw new Error(`jscode2session失败: [${data.errcode}] ${data.errmsg}`);
  }
  return data; // { openid, unionid?, session_key }
}

async function getUserPhoneNumber(phoneCode) {
  const accessToken = await getAccessToken();
  const url = `https://api.weixin.qq.com/wxa/business/getuserphonenumber?access_token=${accessToken}`;
  const resp = await fetch(url, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ code: phoneCode })
  });
  const data = await resp.json();
  if (data.errcode) {
    throw new Error(`getuserphonenumber失败: [${data.errcode}] ${data.errmsg}`);
  }
  return data.phone_info; // { phoneNumber, purePhoneNumber, countryCode }
}

/**
 * 小程序手机号一键登录
 * POST /api/wechat/phone-login
 * body: { loginCode, phoneCode, avatarUrl?, nickName? }
 */
router.post('/phone-login', async (req, res) => {
  try {
    const { loginCode, phoneCode, avatarUrl = null, nickName = null } = req.body || {};

    if (!WECHAT_APPID || !WECHAT_APP_SECRET) {
      return res.error('服务未配置微信AppID/Secret', 500);
    }

    if (!loginCode || !phoneCode) {
      return res.error('缺少必要参数: loginCode 或 phoneCode', 400);
    }

    // 1) 通过 loginCode 获取 openid/unionid
    const sessionData = await jscode2session(loginCode);
    const { openid, unionid = null } = sessionData;

    // 2) 通过 phoneCode 获取手机号
    const phoneInfo = await getUserPhoneNumber(phoneCode);
    const { phoneNumber } = phoneInfo;

    // 3) 用户入库：已存在则更新手机号与登录时间；不存在则创建
    let user = await User.findByOpenid(openid);
    if (!user) {
      user = await User.create({
        openid,
        unionid,
        nickname: nickName,
        avatar_url: avatarUrl,
        phone_number: phoneNumber,
      });
    } else {
      const updateData = { last_login_at: new Date() };
      if (!user.phone_number && phoneNumber) updateData.phone_number = phoneNumber;
      if (nickName) updateData.nickname = nickName;
      if (avatarUrl) updateData.avatar_url = avatarUrl;
      user = await User.update(user.id, updateData);
    }

    // 4) 签发小程序 JWT（与后台管理区分开来）
    const token = jwt.sign(
      {
        type: 'mp',
        userId: user.id,
        openid,
      },
      JWT_SECRET,
      { expiresIn: JWT_EXPIRES_IN }
    );

    const safeUser = {
      id: user.id,
      openid: user.openid,
      unionid: user.unionid || null,
      nickname: user.nickname || null,
      avatar_url: user.avatar_url || null,
      phone_number: user.phone_number || phoneNumber || null,
      last_login_at: user.last_login_at,
      created_at: user.created_at,
    };

    return res.success({ token, user: safeUser }, '登录成功');
  } catch (error) {
    console.error('微信手机号一键登录失败:', error);
    return res.error(error.message || '登录失败', 500);
  }
});

module.exports = router;

